# encoding: utf-8
"""
brightcontent.plugins.trackbacks

Trackbacks end up as comments:
  The Bible is: http://www.ietf.org/rfc/rfc4685.txt

Implementation of http://www.sixapart.com/pronet/docs/trackback_spec
"""

import os, cStringIO
from string import Template
from datetime import *#; from dateutil.relativedelta import *

from Ft.Lib import Uri
import amara

from brightcontent.core import SLUGCHARS
from brightcontent.util import UrlDispatch, get_base_url, web_trigger, quick_xml_multiscan, fixup_namespaces
from brightcontent.core.store import flatfile_repository, ATOM10_NS, COMMON_PREFIXES
from paste.wsgiwrappers import WSGIRequest
from paste.httpexceptions import *
from brightcontent.core.store import COMMON_PREFIXES as BASE_COMMON_PREFIXES
from brightcontent.plugins.comments import CommentStore
COMMON_PREFIXES['thr'] = "http://purl.org/syndication/thread/1.0"

TRACKBACK_TEMPLATE = Template("""
<entry xmlns="http://www.w3.org/2005/Atom"
       xmlns:thr="http://purl.org/syndication/thread/1.0">
  <id>$tid</id>
  <title>$title</title>
  <updated>$now</updated>
  <link href="$parent_id\#$tb_anchor" rel="permalink" title="TrackBack Permalink" />
  <link href="$tid" rel="self" title="Trackback Atom" />
  <link href="$url" ref="source" title="$title" />
  <thr:in-reply-to
    ref="$parent_id"
    type="application/xhtml+xml"
    href="$parent_id"/>
  <summary>$excerpt</summary>
</entry>
""")

TRACKBACK_ERROR = Template("""
<?xml version="1.0" encoding="utf-8"?>
<response>
  <error>1</error>
  <message>$message</message>
</response>""")

TRACKBACK_SUCCESS = """
<?xml version="1.0" encoding="utf-8"?>
<response>
  <error>0</error>
</response>"""

class TrackbackMiddleware(object):
    def __init__(self, application, store, app_conf):
        self.application = application
        self.entry_store = store
        self.store = CommentStore(**app_conf)
        self.app_conf = app_conf # FIXME: temporary until config middleware is working correctly
        self.m = UrlDispatch(self.urls)

    def trackbacks(self, environ, start_response, method, year=None, month=None, day=None, slug=None, **etc):
        print "got trackback url match"
        if not (year and month and day and slug):
            return
        edate = date(int(year), int(month), int(day))
        entries = self.entry_store.index
        for atom_updated, atom_id, atom_published, fn in entries:
            if atom_published.date() == edate:
                entry_id = atom_id
                break
        else:
            entry_id = None

        def POST():
            return self.create_trackback(environ, start_response, entry_id, slug)
        allowed_methods = {'POST' : POST }
        if method in allowed_methods:
            return allowed_methods[method]()
        else:
            return HTTPMethodNotAllowed()(environ, start_response)

    def __call__(self, environ, start_response):
        path_info = environ.get('PATH_INFO', '')
        method = environ.get('REQUEST_METHOD', '')
        if path_info == '': path_info = '/' # FIXME: just a workaround for a paste bug
        self._location = path_info
        func, query_dict = self.m.match(path_info)
        if func:
            return func(self, environ, start_response, method, **query_dict)
        else:
            return self.application(environ, start_response)

    def create_trackback(self, environ, start_response, entry_id, slug):
        from pprint import pprint
        pprint(environ)
        req = WSGIRequest(environ)
        pprint(req.POST)
        title = req.POST.get('title', 'Trackback for %s' % entry_id)
        excerpt = req.POST.get('excerpt', '')
        url = req.POST.get('url', None)
        blog_name = req.POST.get('blog_name', None)
        parent_id = entry_id
        # only the url is required
        if not url:
            start_response('406 Not Acceptable',
                           [('content-type', 'text/xml')])
            message = "Url required"
            result = [TRACKBACK_ERROR.safe_substitute(locals())]
            return result

        print "Creating a trackback."
        # need in locals(): tid, title, now, parent_id, tb_anchor, body
        body = excerpt
        now = datetime.now()
        tb_anchor = '-TB-'+str(now.strftime('%Y%m%d-%H-%M-%S'))
        tid = parent_id + tb_anchor
        now = now.strftime('%Y-%m-%dT%H:%M:%SZ')
        tb_slug = slug + tb_anchor
        content = TRACKBACK_TEMPLATE.safe_substitute(locals())
        print content
        self.store.create_entry(content, tb_slug)
        start_response(
            '201 Created',
            [('Content-type', 'text/xml')]
        )
        return [TRACKBACK_SUCCESS]

    # Only show comments with a single entry a la Sam Ruby 
    urls = (
        (r'/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>[%s]+)/trackbacks/?'%(SLUGCHARS), trackbacks),
    )



